const comUtils = require("./common");

/**
 * @description: 数字格式化
 * @param {String|Number}
 * @return {String}
 */

function checkTime(idx) {
  return ("0" + idx).slice(-2);
}

/**
 * @description:
 * @param {String|Number|Date} dateParams // 日期对象  时间戳(数字 , 字符串)
 * @param {String} formatKey // DD hh mm ss 正则匹配
 * @return {Object|null} // null  时间差已过
 */
function leftDate(dateParams, formatKey) {
  if (dateParams !== undefined) {
    const paramsType = comUtils.toClass(dateParams);
    let endDate = null;
    if (paramsType === "String" || paramsType === "Number") {
      if (dateType === "String") {
        dateParams = dateParams.replace(/\-/gm, "/");
      }
      endDate = new Date(dateParams);
    } else if (paramsType === "Date") {
      endDate = dateParams;
    } else {
      throw TypeError("param dateParams type must be [String,Number,Date]");
    }
    const leftTimes = endDate.getTime() - new Date().getTime();
    if (leftTimes >= 0) {
      const leftDays = checkTime(parseInt(leftTimes / 1000 / 60 / 60 / 24));
      const leftHours = checkTime(parseInt((leftTimes / 1000 / 60 / 60) % 24));
      const leftMinutes = checkTime(parseInt((leftTimes / 1000 / 60) % 60));
      const leftSeconds = checkTime(parseInt((leftTimes / 1000) % 60));
      // 格式化字符串
      let formatVal;
      if (formatKey && typeof formatKey === "string") {
        formatVal = formatKey.replace(
          /(DD)|(hh)|(mm)|(ss)/gm,
          function (match, DD, hh, mm, ss) {
            if (DD) {
              return leftDays;
            } else if (hh) {
              return leftHours;
            } else if (mm) {
              return leftMinutes;
            } else if (ss) {
              return leftSeconds;
            }
          }
        );
      } else {
        throw Error("param formatKey is required or type must be String");
      }
      return {
        days: leftDays,
        hours: leftHours,
        minutes: leftMinutes,
        seconds: leftSeconds,
        formatVal,
      };
    } else {
      return null;
    }
  } else {
    throw new ReferenceError("param dateParams must be required");
  }
}

/**
 * @description:
 * @param {String|Number|Date} dateParams // 日期对象  时间戳(数字 , 字符串)
 * @param {String} formatKey // 格式化文本  YYYY MM DD hh mm ss 正则匹配
 * @return {Object}
 */
function formatDate(dateParams, formatKey = "YYYY-MM-DD hh:mm:ss") {
  const dateType = comUtils.toClass(dateParams);
  let dateObj;
  if (dateType === "Number" || dateType === "String") {
    if (dateType === "String") {
      dateParams = dateParams.replace(/\-/gm, "/");
    }
    dateObj = new Date(dateParams);
  } else if (dateType === "Date") {
    dateObj = dateParams;
  } else {
    throw TypeError("param dateParams type must be [String,Number,Date]");
  }
  const year = dateObj.getFullYear();
  const month = checkTime(dateObj.getMonth() + 1);
  const date = checkTime(dateObj.getDate());
  const hours = checkTime(dateObj.getHours());
  const minutes = checkTime(dateObj.getMinutes());
  const seconds = checkTime(dateObj.getSeconds());
  let formatVal;
  // 格式化字符串
  if (formatKey && typeof formatKey === "string") {
    formatVal = formatKey.replace(
      /(YYYY)|(MM)|(DD)|(hh)|(mm)|(ss)/gm,
      function (match, YYYY, MM, DD, hh, mm, ss) {
        if (YYYY) {
          return year;
        } else if (MM) {
          return month;
        } else if (DD) {
          return date;
        } else if (hh) {
          return hours;
        } else if (mm) {
          return minutes;
        } else if (ss) {
          return seconds;
        }
      }
    );
  } else {
    throw Error("param formatKey is required or type must be String");
  }
  return {
    year,
    month,
    date,
    hours,
    minutes,
    seconds,
    formatVal,
    timestamp: dateObj.getTime(),
  };
}

function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null;
  }
  const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
  let date;
  if (typeof time === "object") {
    date = time;
  } else {
    if (typeof time === "string") {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time);
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), "/");
      }
    }

    if (typeof time === "number" && time.toString().length === 10) {
      time = time * 1000;
    }
    date = new Date(time);
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === "a") {
      return ["日", "一", "二", "三", "四", "五", "六"][value];
    }
    return value.toString().padStart(2, "0");
  });
  return time_str;
}


// 获取元素信息
function getRect(selector) {
  return new Promise((resolve) => {
      uni.createSelectorQuery()
          .in(this)
          .select(selector)
          .boundingClientRect()
          .exec((rect = []) => resolve(rect[0]));
  });
}
// 获取集合元素信息
function getAllRect(selector) {
  return new Promise((resolve) => {
      uni.createSelectorQuery()
          .in(this)
          .selectAll(selector)
          .boundingClientRect()
          .exec((rect = []) => resolve(rect[0]));
  });
}

// 滚动到指定元素
function getCenterViewDy(toParams) {
  if( !toParams ){
      return
  }
  const { 
      index //当前索引
      , listClass // scroll-view class或者 id
      , itemClass // scroll-view 子元素item class
  } = toParams
  const vm = this;
  return Promise.all([
    getAllRect.call(vm, itemClass),
    getRect.call(vm, listClass),
  ]).then(([tabRects, navRect]) => {
    const tabRect = tabRects[index];
    const offsetLeft = tabRects
      .slice(0, index)
      .reduce((prev, curr) => prev + curr.width, 0);
    const dy = offsetLeft - (navRect.width - tabRect.width) / 2;
    return Promise.resolve({ dy });
  });
}


module.exports = {
  checkTime,
  formatDate,
  leftDate,
  parseTime,
  getRect,
  getAllRect,
  getCenterViewDy
};
